package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.StringUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.po.Note;
import com.tianji.learning.domain.query.NoteQuery;
import com.tianji.learning.domain.vo.NoteVo;
import com.tianji.learning.mapper.NoteMapper;
import com.tianji.learning.service.INoteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yb0os1
 * @since 2025-03-31
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note> implements INoteService {
    private final UserClient userClient;
    /**
     * 新增笔记
     * @param note
     */
    @Override
    public void saveNote(Note note) {
        //1、参数校验
        if (note==null){
            log.error("新增笔记参数为空");
            throw new BizIllegalException("新增笔记参数为空");
        }
        note.setAuthorId(UserContext.getUser());
        note.setCreateTime(LocalDate.now());
        //2、保存笔记
        boolean isSuccess = save(note);
        if (!isSuccess){
            log.error("新增笔记失败");
        }
    }

    @Override
    public void gatherOrCancelNote(Integer noteId, boolean isGather) {
        //1、参数校验
        if (noteId==null){
            log.error("笔记id为空");
            throw new BizIllegalException("笔记id为空");
        }
        //2、根据noteId查询别人的笔记
        Note note = getById(noteId);
        if (note==null){
            log.error("笔记不存在");
            return;
        }
        //3、采集还是取消
        if (isGather){
            //设置参数
            note.setIsPrivate(true);
            note.setGatherId(noteId);
            note.setIsGathered(true);
            saveNote(note);
        }else{
            boolean b = removeById(noteId);
            if (!b){
                log.error("取消收藏失败");
                throw new BizIllegalException("取消收藏失败");
            }
        }
    }

    @Override
    public void updateNote(Integer id, Note note) {
        if (id==null||note==null){
            log.error("id为空");
            throw new BizIllegalException("id为空");
        }
        boolean success = lambdaUpdate().eq(Note::getId, id)
                .set(StringUtils.isNotBlank(note.getContent()), Note::getNoteMoment, note.getNoteMoment())
                .set(note.getIsPrivate() != null, Note::getIsPrivate, note.getCourseId())
                .update();
        if (!success){
            log.error("更新笔记失败");
            throw new BizIllegalException("更新笔记失败");
        }
    }

    @Override
    public void deleteNote(Integer id) {
        if (id==null){
            log.error("id为空");
            throw new BizIllegalException("id为空");
        }
        boolean success = removeById(id);
        if (!success){
            log.error("删除笔记失败");
            throw new BizIllegalException("删除笔记失败");
        }
    }

    /**
     * 分页查询笔记
     * @param query
     * @return
     */
    @Override
    public PageDTO pageQueryNotes(NoteQuery query) {
        if (query==null){
            log.error("查询参数为空");
            return PageDTO.empty(0L,0L);
        }
        if (query.getOnlyMine()==null){
            throw new BizIllegalException("是否只查询我的笔记为必填项");
        }
        //进行分页查询
        Long userId = UserContext.getUser();
        Page<Note> page = lambdaQuery().eq(query.getOnlyMine(), Note::getAuthorId, userId)
                .eq(query.getCourseId() != null, Note::getCourseId, query.getCourseId())
                .eq(query.getSectionId() != null, Note::getSectionId, query.getSectionId())
                .eq(!query.getOnlyMine(),Note::getIsPrivate, false)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<Note> records = page.getRecords();
        if (CollUtils.isEmpty(records)){
            log.error("查询结果为空");
            return PageDTO.empty(page);
        }
        //组建返回结果 需要补充authorName authorIcon
        List<NoteVo> noteVos = BeanUtils.copyToList(records, NoteVo.class);
        Set<Long> authorIds = records.stream().map(Note::getAuthorId).collect(Collectors.toSet());
        Map<Long,String> id2Name = new HashMap<>(authorIds.size());
        Map<Long,String> id2Icon = new HashMap<>(authorIds.size());
        List<UserDTO> userDTOS = userClient.queryUserByIds(authorIds);
        if (CollUtils.isEmpty(userDTOS)){
            log.error("查询用户信息为空");
            return PageDTO.empty(page);
        }
        userDTOS.forEach(u->{
            id2Name.put(u.getId(),u.getName());
            id2Icon.put(u.getId(),u.getIcon());
        });

        noteVos = noteVos.stream().peek(noteVo -> {
            noteVo.setAuthorName(id2Name.get(noteVo.getAuthorId()));
            noteVo.setAuthorIcon(id2Icon.get(noteVo.getAuthorId()));
        }).collect(Collectors.toList());
        return PageDTO.of(page,noteVos);
    }

}
